/************************************************************
 * Project Name         [Thinking_In_Java]
 * File Name            [FontDialog.java]
 * Creation Date        [11-Jul-2014]
 * 
 * Copyright© ge.y.yang@gmail.com All Rights Reserved
 * 
 * Work hard, play harder, think big and keep fit
 ************************************************************/
package pkg_02_gui.notepad_V1.ui.font;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GraphicsEnvironment;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JColorChooser;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.SwingConstants;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

/**
 * 
 * @author 不落的太阳(Sean Yang)
 * @version 1.0
 * @since JDK 6
 * 
 */
public class FontDialog extends JFrame implements ActionListener {

	private static final long serialVersionUID = -4423600168680356626L;

	private JDialog fontDialog = null;// 字体对话框
	private JTextField fontNameField = null; // 字体名称
	private JTextField fontSizeField = null; // 字体大小
	private JTextField fontStyleField = null;// 字体风格

	private final int fontStyleConstant[] = { Font.PLAIN, Font.BOLD,
			Font.ITALIC, Font.BOLD + Font.ITALIC };

	private JList<String> fontNameList = null;
	private JList<String> fontSizeList = null;
	private JList<String> fontStyleList = null;

	private Color backgroundColor = null;
	private Color fontColor = null;

	private JLabel sampleLabel = null;
	private Font newFont = null;

	private JButton fontSelectedButton = null; // 选择按钮
	private JButton fontCancelButton = null; // 撤销按钮

	private JTextArea textArea = null;

	private void init() {
		Font currentFont = textArea.getFont();

		fontDialog = new JDialog(this, "字体设置", true);
		Container container = fontDialog.getContentPane();

		backgroundColor = textArea.getBackground();
		fontColor = textArea.getBackground();

		/** ***********改变背景颜色*********** */
		JPanel backgroundColorPanel = new JPanel(); // 背景颜色面板
		backgroundColorPanel.setLayout(new BorderLayout());
		backgroundColorPanel
				.setBorder(BorderFactory.createTitledBorder("背景颜色"));

		final JLabel backgroundChangeLabel = new JLabel("单击改变背景颜色");
		backgroundChangeLabel.setOpaque(true); // 设置透明
		backgroundChangeLabel.setHorizontalAlignment(SwingConstants.CENTER);// 设置文字居中
		backgroundChangeLabel.setBackground(Color.WHITE); // 设置背景色为白色, 为文本区初始化颜色
		backgroundChangeLabel.addMouseListener(new MouseAdapter() {
			@Override
			public void mousePressed(MouseEvent e) {
				Color color = JColorChooser.showDialog(FontDialog.this,
						"设置背景颜色", Color.BLACK);
				if (color != null) {// null表示用户按下了Cancel按钮
					backgroundColor = color;
					backgroundChangeLabel.setBackground(backgroundColor);
					sampleLabel.setBackground(backgroundColor);
				}
			}
		});
		backgroundColorPanel.add(backgroundChangeLabel, BorderLayout.CENTER);

		/** ***********改变字体颜色*********** */
		JPanel fontColorPanel = new JPanel();// 字体颜色面板
		fontColorPanel.setLayout(new BorderLayout());
		fontColorPanel.setBorder(BorderFactory.createTitledBorder("字体颜色"));

		final JLabel fontColorChangeLabel = new JLabel("单击改变字体颜色");
		fontColorChangeLabel.setOpaque(true); // 设置透明
		fontColorChangeLabel.setHorizontalAlignment(SwingConstants.CENTER);// 设置文字居中
		fontColorChangeLabel.setBackground(Color.BLACK);
		fontColorChangeLabel.addMouseListener(new MouseAdapter() {
			@Override
			public void mousePressed(MouseEvent e) {
				Color color = JColorChooser.showDialog(FontDialog.this,
						"设置字体颜色", Color.BLACK);
				if (color != null) { // null表示用户按下了Cancel按钮
					fontColor = color;
					fontColorChangeLabel.setBackground(fontColor);
					sampleLabel.setForeground(fontColor);
				}
			}
		});
		fontColorPanel.add(fontColorChangeLabel, BorderLayout.CENTER);

		/** ***********字体名称*********** */
		JLabel fontNameLabel = new JLabel("字体(F)");
		initFontNamePanel(currentFont, fontNameLabel);

		/** ***********字体大小*********** */
		JLabel fontSizeLabel = new JLabel("大小(S)");
		initFontSizePanel(currentFont, fontSizeLabel);

		/** ***********字体风格*********** */
		JLabel fontStyleLabel = new JLabel("字形(Y)");
		initFontStylePanel(currentFont, fontStyleLabel);

		/** ***********按钮设定*********** */
		fontSelectedButton = new JButton("确定");
		fontSelectedButton.addActionListener(this);
		fontCancelButton = new JButton("取消");
		fontCancelButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				fontDialog.dispose();
			}
		});

		/** ***********示例面板*********** */
		sampleLabel = new JLabel("Notepad");
		sampleLabel.setOpaque(true);
		sampleLabel.setHorizontalAlignment(SwingConstants.CENTER);
		sampleLabel.setBackground(Color.WHITE);
		sampleLabel.setForeground(Color.BLACK);

		JPanel previewPanel = new JPanel(new BorderLayout()); // 预览面板
		previewPanel.setBorder(BorderFactory.createTitledBorder("预览")); // 设置边框标题
		previewPanel.add(sampleLabel, BorderLayout.CENTER);

		/** ***********字体名称面板*********** */
		JPanel fontNamePanel = new JPanel();// 字体面板
		fontNamePanel.add(fontNameLabel);
		fontNamePanel.add(fontNameField);
		fontNamePanel.add(new JScrollPane(fontNameList));

		/** ***********字体大小面板*********** */
		JPanel fontSizePanel = new JPanel();// 字号面板
		fontSizePanel.add(fontSizeLabel);
		fontSizePanel.add(fontSizeField);
		fontSizePanel.add(new JScrollPane(fontSizeList));

		/** ***********字体风格面板*********** */
		JPanel fontStylePanel = new JPanel(); // 字形面板
		fontStylePanel.add(fontStyleLabel);
		fontStylePanel.add(fontStyleField);
		fontStylePanel.add(new JScrollPane(fontStyleList));

		/** ***********组合面板*********** */
		// 存放确定和取消按钮的面板
		JPanel basePanel = new JPanel();
		basePanel.setLayout(new FlowLayout());
		basePanel.add(fontSelectedButton);
		basePanel.add(fontCancelButton);

		// 存放字体, 字形, 字号, 颜色, 预览等面板
		JPanel mainPanel = new JPanel();
		mainPanel.setLayout(new GridLayout(2, 3));
		mainPanel.add(fontNamePanel);
		mainPanel.add(fontStylePanel);
		mainPanel.add(fontSizePanel);
		mainPanel.add(backgroundColorPanel);
		mainPanel.add(fontColorPanel);
		mainPanel.add(previewPanel);

		container.add(basePanel, BorderLayout.SOUTH);
		container.add(mainPanel, BorderLayout.CENTER);

		updateSample();

		fontDialog.setSize(450, 340);
		fontDialog.setLocation(200, 200);
		fontDialog.setResizable(false);
		fontDialog.setVisible(true);
	}

	/**
	 * 字体名称
	 * 
	 * @param currentFont
	 * @param fontNameLabel
	 */
	private void initFontNamePanel(Font currentFont, JLabel fontNameLabel) {
		fontNameLabel.setPreferredSize(new Dimension(80, 20));
		fontNameField = new JTextField(12);
		fontNameField.setText(currentFont.getFontName());
		fontNameField.selectAll();
		fontNameField.setPreferredSize(new Dimension(20, 20));

		final String[] fontNames = GraphicsEnvironment
				.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
		fontNameList = new JList<String>(fontNames);

		int defaultFontNameIndex = 0;
		for (int i = 0; i < fontNames.length; i++) {
			if (fontNames[i].equals(currentFont.getFontName())) {
				defaultFontNameIndex = i;
				break;
			}
		}
		fontNameList.setSelectedIndex(defaultFontNameIndex);
		fontNameList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);// 设置字体单选
		fontNameList.setVisibleRowCount(5);
		fontNameList.setFixedCellWidth(120);
		fontNameList.setFixedCellHeight(15);
		fontNameList.addListSelectionListener(new ListSelectionListener() {
			@Override
			public void valueChanged(ListSelectionEvent e) {
				fontNameField.setText(fontNames[fontNameList.getSelectedIndex()]);
				fontNameField.requestFocus();
				fontNameField.selectAll();
				updateSample();
			}
		});
	}

	/**
	 * 字体大小
	 * 
	 * @param currentFont
	 * @param fontSizeLabel
	 */
	private void initFontSizePanel(Font currentFont, JLabel fontSizeLabel) {
		fontSizeLabel.setPreferredSize(new Dimension(80, 20));
		fontSizeField = new JTextField(8);
		fontSizeField.setText(currentFont.getSize() + "");
		fontSizeField.selectAll();
		fontSizeField.setPreferredSize(new Dimension(20, 20));
		final String[] fontSizes = { "8", "9", "10", "11", "12", "14", "16",
				"18", "20", "22", "24", "26", "28", "36", "48", "72" };
		fontSizeList = new JList<String>(fontSizes);
		int defauleFontSizeIndex = 0;
		for (int i = 0; i < fontSizes.length; i++) {
			if (fontSizes[i].equals(currentFont.getSize() + "")) {
				defauleFontSizeIndex = i;
				break;
			}
		}
		fontSizeList.setSelectedIndex(defauleFontSizeIndex);
		fontSizeList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		fontSizeList.setVisibleRowCount(5);
		fontSizeList.setFixedCellWidth(70);
		fontSizeList.setFixedCellHeight(15);
		fontSizeList.addListSelectionListener(new ListSelectionListener() {
			@Override
			public void valueChanged(ListSelectionEvent event) {
				fontSizeField.setText(fontSizes[fontSizeList.getSelectedIndex()]);
				fontSizeField.requestFocus();
				fontSizeField.selectAll();
				updateSample();
			}
		});
	}

	/**
	 * 字体样式
	 * 
	 * @param currentFont
	 * @param fontStyleLabel
	 */
	private void initFontStylePanel(Font currentFont, JLabel fontStyleLabel) {
		fontStyleLabel.setPreferredSize(new Dimension(80, 20));
		fontStyleField = new JTextField(10);
		if (currentFont.getStyle() == Font.PLAIN) {
			fontStyleField.setText("常规");
		} else if (currentFont.getStyle() == Font.BOLD) {
			fontStyleField.setText("粗体");
		} else if (currentFont.getStyle() == Font.ITALIC) {
			fontStyleField.setText("斜体");
		} else if (currentFont.getStyle() == (Font.BOLD + Font.ITALIC)) {
			fontStyleField.setText("粗斜体");
		}
		fontStyleField.setPreferredSize(new Dimension(20, 20));
		final String[] fontStyleNames = { "常规", "粗体", "斜体", "粗斜体" };
		fontStyleList = new JList<String>(fontStyleNames);
		fontStyleList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);// 设置字形单选
		if (currentFont.getStyle() == Font.PLAIN) {
			fontStyleList.setSelectedIndex(0);
		} else if (currentFont.getStyle() == Font.BOLD) {
			fontStyleList.setSelectedIndex(1);
		} else if (currentFont.getStyle() == Font.ITALIC) {
			fontStyleList.setSelectedIndex(2);
		} else if (currentFont.getStyle() == (Font.BOLD + Font.ITALIC)) {
			fontStyleList.setSelectedIndex(3);
		}
		fontStyleList.setVisibleRowCount(5);
		fontStyleList.setFixedCellWidth(110);
		fontStyleList.setFixedCellHeight(15);
		fontStyleList.addListSelectionListener(new ListSelectionListener() {
			@Override
			public void valueChanged(ListSelectionEvent event) {
				fontStyleField.setText(fontStyleNames[fontStyleList
						.getSelectedIndex()]);
				fontStyleField.requestFocus();
				fontStyleField.selectAll();
				updateSample();
			}
		});

	}

	public FontDialog(JTextArea textArea) {
		this.textArea = textArea;
		init();
	}

	/**
	 * 更新示例标签
	 */
	private void updateSample() {
		Font sampleFont = new Font(fontNameField.getText(),
				fontStyleConstant[fontStyleList.getSelectedIndex()],
				Integer.parseInt(fontSizeField.getText()));
		sampleLabel.setFont(sampleFont);
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if (e.getSource() == fontSelectedButton) {
			newFont = new Font(fontNameField.getText(),
					fontStyleConstant[fontStyleList.getSelectedIndex()],
					Integer.parseInt(fontSizeField.getText()));
			fontDialog.dispose();
			textArea.setFont(newFont);
			textArea.setBackground(backgroundColor);
			textArea.setForeground(fontColor);
		}
	}

	public Color getBackgroundColor() {
		return backgroundColor;
	}

	public Color getFontColor() {
		return fontColor;
	}

	public Font getNewFont() {
		return newFont;
	}
}